﻿using System.Collections.Generic;
using NapazEngine.Framework.Messages;

namespace NapazEngine.Framework
{
    class Story: FrameworkElement
    {
        private List<IScene> scenes;
        private int sceneIndex;

        public Story(): base()
        {
            scenes = new List<IScene>();
            sceneIndex = -1;
        }

        /// <summary>
        /// Adds an IScene object to the story
        /// </summary>
        /// <param name="scene"></param>
        public void AddScene(IScene scene)
        {
            scenes.Add(scene);
        }

        /// <summary>
        /// Removes an IScene object to the story
        /// </summary>
        /// <param name="scene"></param>
        public void RemoveScene(IScene scene)
        {
            scenes.Remove(scene);
        }

        /// <summary>
        /// Notify the story of something
        /// </summary>
        /// <param name="message"></param>
        public override void Notify(GameMessage message)
        {
            if (message is StoryMessage)
            {
                StoryMessage sm = (StoryMessage)message;

                switch (sm.Type)
                {
                    case StoryMessage.StoryAction.Forward:
                        scenes[sceneIndex].Stop();
                        scenes[sceneIndex++].Start();
                        break;
                    case StoryMessage.StoryAction.Load:
                        scenes[sceneIndex].Stop();
                        sceneIndex = scenes.IndexOf(sm.SceneToLoad);
                        scenes[sceneIndex].Start();
                        break;

                }
            }
        }

        /// <summary>
        /// Register to receive events from the story
        /// </summary>
        /// <param name="element"></param>
        public override void Register(FrameworkElement element)
        {
            base.Register(element);
        }

        /// <summary>
        /// Unregister to receive events from the story
        /// </summary>
        /// <param name="element"></param>
        public override void Unregister(FrameworkElement element)
        {
            base.Unregister(element);
        }
    }

    /// <summary>
    /// StoryMessage class to indicate the type of message the story should handle
    /// </summary>
    public class StoryMessage: GameMessage
    {
        /// <summary>
        /// The type 
        /// </summary>
        public enum StoryAction { Forward, Load };

        /// <summary>
        /// The type of action that this message should convey
        /// </summary>
        public StoryAction Type { get; set; }

        /// <summary>
        /// If set, will tell the story to load a specific scene
        /// </summary>
        public IScene SceneToLoad { get; private set; }


        public StoryMessage() : base()
        {
            this.messageType = MessageType.Event;
        }

        /// <summary>
        /// Sets the type of story message this will be
        /// </summary>
        /// <param name="type">The type of story message</param>
        /// <param name="scene">Scene to load. Applies only to StoryAction.Load types</param>
        public void SetType(StoryAction type, IScene scene)
        {
            if (type == StoryAction.Load && scene != null)
            {
                Type = StoryAction.Load;
                SceneToLoad = scene;
            }
            else
            {
                Type = type;

                //TODO
            }
        }

        /// <summary>
        /// Tells the story to load a specific scene
        /// </summary>
        /// <param name="sceneToLoad"></param>
        public StoryMessage(IScene sceneToLoad) : base()
        {
            this.messageType = MessageType.Event;
            Type = StoryAction.Load;
            SceneToLoad = sceneToLoad;
        }
    }
}
